const FUN = require('../comm/func');
const rCache = require('../model/redis_cache');
const DB = require('../model/model_data');
const dbHelp = require('../comm/db-helper');
const timLib = require('../comm/time-lib');
const mbLib = require('../comm/modbus-lib');
const PMR=require('../utils/policyManger');
const dataCalc = require('../comm/data-calc');
const FFTW = require('fftw-js');

module.exports = class Bulk_FFT
{
  //将数据库选项缓存到redis
  //policy 来自数据库的记录
  //opts 数据库json字段的解析对象
  //CacheCallback 存储执行函数
  static InitCache(policy,opts,CacheCallback)
  {
    let obj=PMR.baseParam(policy);//即将缓存到redis的参数

    //检查json选项
    if( parseInt(policy.record_limit)==0 ||
        parseInt(opts.reg_total)==0 ||
        parseInt(opts.reg_total)<=parseInt(opts.reg_hd_num) )
    {
      console.error('wrong template params',policy.id);
      return false;
    }

    //json options参数存储
    obj.record_limit = policy.record_limit;//数据库条数上限
    obj.reg_total=opts.reg_total;//寄存器总数
    obj.reg_hd_num=opts.reg_hd_num;//头部几个附加寄存器

    //数据库处理
    dbHelp.createTab(obj.table,policy.uid);

    //缓存主站参数
    obj.hwid = policy.master;
    CacheCallback(policy.id, policy.master, obj);//记录到缓存

    //开启定时器
    //policyMan.setSecInter(obj.policy_id,obj.fetch_period);
  }//end InitCache

  //转换函数
  static fft(din)
  {
    let fftr = new FFTW.FFT(din.length);//转换器
    let transform = fftr.forward(din);//开始转换
    fftr.dispose();//释放转换器
    return transform;
  }

  // 处理mq传入的json数据
  // topic = {project,devType,func,devId}
  // dConf即InitCache中的obj
  // dataBuf即mq消息内容，buf对象
  static async DataIn(topic, dConf, dataBuf)
  {
    //if(dataBuf.length<=8) pcyLog('data',dataBuf);
    //else pcyLog('data',dataBuf.length);
    mbLib.mbPacketParse(topic.func, dConf, dataBuf, (last,sConf)=>{
      rCache.push(PMR.rdNode(dConf),last.addr,last.regStart+'$'+JSON.stringify(dataBuf),3600);

      //pcyLog('last',last.regStart,last.regNum,dConf.reg_total);
      if(Number(last.regStart)+Number(last.regNum) >= dConf.reg_total)
      {
        rCache.fetchAll(PMR.rdNode(dConf),last.addr).then((d)=>{//取出所有数据
          rCache.del(PMR.rdNode(dConf),last.addr);//删除缓存
          let orgData=[];
          let cnt=0;
          d.some((json,i)=>{
            let jsonArry=json.split('$');
            let regAddr=parseInt(jsonArry[0]);
            let buf=JSON.parse(jsonArry[1]);

            for(let n=3;n<buf.data.length-2;n+=2)
            {
              let onum=parseInt(buf.data[n])*256+parseInt(buf.data[n+1]);
              if(onum>0x8000) onum-=0x10000;//负数
              orgData[cnt++]=onum;
              //if(cnt < 10) pcyLog(buf.data[n],buf.data[n+1],orgData[cnt-1]);//for debug
              if(cnt>=dConf.reg_total) break;
            }
          })

          let orgNum=parseInt(dConf.reg_total)-parseInt(dConf.reg_hd_num);
          let temp=orgData[0];//第一字节是温度
          if(parseInt(dConf.reg_hd_num)) orgData.splice(0,dConf.reg_hd_num);//删除前面的温度数值
          orgData.splice(orgNum,orgData.length-orgNum);//1600个加速度数据 mg2/s

          //存储原始数据
          //let json1='{"type":"org","temp":'+temp+',"data":"'+orgData.join(',')+'"}';
          //db.newRcd(dConf.table,'hwid,policy_id,addr,json,stamp',[dConf.hwid,dConf.policy_id,last.addr,json1,timLib.NowStamp()]);

          //计算加速度数据
          let v=[];
          let v_start=0;
          let t=0.5/orgNum;
          let offset=orgData.reduce((prev,cur,i,a)=>{return Number(prev)+Number(cur);})/orgData.length;

          for(let n in orgData)
          {
            orgData[n]-=offset;//减去偏移值
            orgData[n]=Number(orgData[n])*9.8;
            v_start+=orgData[n]*t;
            orgData[n]=orgData[n].toFixed(3);
            v[n]=v_start.toFixed(4);
          }

          //时域加速度
          let json11='{"type":"acc","temp":'+temp+',"data":"'+orgData.join(',')+'"}';
          DB.newRcd(dConf.uid, dConf.table, 'hwid,policy_id,addr,json,stamp',
                      [dConf.hwid, dConf.policy_id, last.addr, json11, timLib.NowStamp()]);

          //存储速度数据
          let json2='{"type":"speed","data":"'+v.join(',')+'"}';
          DB.newRcd(dConf.uid, dConf.table, 'hwid,policy_id,addr,json,stamp',
                      [dConf.hwid, dConf.policy_id, last.addr, json2, timLib.NowStamp()]);

          //计算频域
          let fft=this.fft(orgData);
          let out_jsd=[];
          for(let n=0;n<orgNum;n+=2)
          {
            let x=Number(fft[n]).toFixed(4);
            let r=Number(fft[n+1]).toFixed(4);
            let jsd=Math.sqrt(x*x+r*r)*9.8/800/1000;
            out_jsd.push(jsd.toFixed(3));
          }

          //存储频域
          let json3='{"type":"fft","data":"'+out_jsd.join(',')+'"}';
          DB.newRcd(dConf.uid, dConf.table, 'hwid,policy_id,addr,json,stamp',
                    [dConf.hwid, dConf.policy_id, last.addr, json3, timLib.NowStamp()]);

          //删除历史冗余
          dataCalc.dbRecordTidy(dConf.uid,dConf.table,dConf.policy_id,dConf.record_limit);

          //通知前端
          PMR.policyInform('update',dConf);
        })//end fetchAll
      }//endif

    });
  }


}